package topin.facecat.FaceCat.Android

import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.graphics.Canvas
import android.graphics.Rect
import android.os.Handler
import android.util.DisplayMetrics
import android.view.MotionEvent
import android.view.View
import android.view.WindowManager
import facecat.topin.btn.FCButton
import facecat.topin.core.*
import facecat.topin.div.FCDiv
import facecat.topin.div.FCMenu
import facecat.topin.div.FCSplitLayoutDiv
import facecat.topin.grid.FCGrid
import facecat.topin.input.*
import facecat.topin.scroll.FCHScrollBar
import facecat.topin.scroll.FCScrollBar
import facecat.topin.scroll.FCVScrollBar
import facecat.topin.tab.FCTabPage
import topin.facecat.FaceCat.UI.ArrowButtonM
import topin.facecat.FaceCat.UI.RibbonButton
import topin.facecat.FaceCat.UI.ScrollButtonM
import java.util.*


/*
* 设备对接
*/
class AndroidHost : FCHost(), Runnable {
    /*
     * 裁剪区域
     */
    private val m_clipBounds =
        ArrayList<Rect>()

    /*
     * 句柄
     */
    var m_handler: Handler? = null

    /*
     * 触摸位置
     */
    private var m_mousePoint = FCPoint()

    /*
     * 正在运行的秒表ID
     */
    private val m_runningTimerIDs = ArrayList<Int>()

    /*
     * 线程状态
     */
    var m_threadState = 0

    /*
     * 全部秒表
     */
    private val m_timers =
        HashMap<Int, AndroidTimer?>()
    private var m_allowOperate = false

    /*
     * 允许操作
     */
    override fun allowOperate(): Boolean {
        return m_allowOperate
    }

    /*
     * 设置是否允许操作
     */
    override fun setAllowOperate(value: Boolean) {
        m_allowOperate = value
    }

    private var m_allowPartialPaint = true

    /*
     * 是否允许局部绘图
     */
    override fun allowPartialpaint(): Boolean {
        return m_allowPartialPaint
    }

    /*
     * 设置是否允许局部绘图
     */
    override fun setAllowPartialPaint(value: Boolean) {
        m_allowPartialPaint = value
    }

    private var m_native: FCNative? = null

    /*
     * 方法库
     */
    override fun getNative(): FCNative {
        return m_native!!
    }

    /*
     * 设置方法库
     */
    override fun setNative(value: FCNative) {
        m_native = value
    }

    private var m_view: View? = null

    /*
     * 获取视图
     *//*
     * 设置视图
     */
    var view: View?
        get() = m_view
        set(value) {
            m_view = value
            m_handler = Handler(view!!.context.mainLooper)
            val t = Thread(this)
            t.start()
        }

    /*
     * 视图是否可见
     *//*
     * 设置视图是否可见
     */
    var isViewVisible = true

    /*
     * 开始跨线程调用
     */
    override fun beginInvoke(control: FCView, args: Any) {
        synchronized(this) {
            m_handler!!.post { control!!.onInvoke(args) }
        }
    }

    /*
     * 剪贴板
     */
    private var m_clipboard: ClipboardManager? = null

    /*
     * 复制到剪贴板
     */
    override fun copy(text: String) {
        if (m_clipboard == null) {
            m_clipboard = m_view!!.context
                .getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
        }
        val clipData = ClipData.newPlainText(null, text)
        m_clipboard!!.setPrimaryClip(clipData)
    }

    /*
     * 创建内部视图
     * parent 父视图
     * clsid ID
     */
    override fun createInternalView(parent: FCView, clsid: String): FCView {
        if (parent as? FCSplitLayoutDiv != null) {
            if (clsid == "splitter") {
                val splitter = FCButton()
                splitter.backColor = FCColor.rgba(0, 0, 0, 25)
                splitter.borderColor = FCColor.rgba(200, 200, 200, 100)
                splitter.size = FCSize(5, 5)
                return splitter
            }
        }
        val scrollBar =
            parent as? FCScrollBar
        if (scrollBar != null) {
            scrollBar.backColor = FCColor.None
            scrollBar.borderColor = FCColor.None
            scrollBar.size = FCSize(8, 8)
            if (clsid == "addbutton") {
                val addButton = RibbonButton()
                addButton.size = FCSize(8, 8)
                if (scrollBar as? FCHScrollBar != null) {
                    addButton.width = 0
                } else {
                    addButton.height = 0
                }
                return addButton
            } else if (clsid == "backbutton") {
                val button = FCButton()
                button.backColor = FCColor.None
                button.borderColor = FCColor.None
                return button
            } else if (clsid == "scrollbutton") {
                val scrollButton = ScrollButtonM()
                scrollButton.setAllowDrag(true)
                scrollButton.backColor = FCColor.rgba(94, 102, 115, 200)
                scrollButton.borderColor = FCColor.None
                scrollButton.cornerRadius = 10
                return scrollButton
            } else if (clsid == "reducebutton") {
                val reduceButton = RibbonButton()
                reduceButton.size = FCSize(8, 8)
                if (scrollBar as? FCHScrollBar != null) {
                    reduceButton.width = 0
                } else {
                    reduceButton.height = 0
                }
                return reduceButton
            }
        }
        if (parent as? FCTabPage != null) {
            if (clsid == "headerbutton") {
                val button = RibbonButton()
                button.setAllowDrag(true)
                val size = FCSize(100, 30)
                button.size = size
                return button
            }
        }
        val comboBox = parent as? FCComboBox
        if (comboBox != null) {
            if (clsid == "dropdownbutton") {
                val dropDownButton = ArrowButtonM()
                dropDownButton.arrowType = 4
                dropDownButton.setDisplayOffset(false)
                val width = comboBox.width
                val height = comboBox.height
                val size = FCSize(25, height)
                dropDownButton.size = size
                val location = FCPoint(width - 25, 0)
                dropDownButton.location = location
                return dropDownButton
            } else if (clsid == "dropdownmenu") {
                val comboBoxMenu = FCComboBoxMenu()
                comboBoxMenu.comboBox = comboBox
                comboBoxMenu.setPopup(true)
                val size = FCSize(100, 200)
                comboBoxMenu.size = size
                return comboBoxMenu
            }
        }
        val datePicker =
            parent as? FCDateTimePicker
        if (datePicker != null) {
            if (clsid == "dropdownbutton") {
                val dropDownButton = ArrowButtonM()
                dropDownButton.arrowType = 4
                dropDownButton.setDisplayOffset(false)
                val width = datePicker.width
                val height = datePicker.height
                val size = FCSize(25, height)
                dropDownButton.size = size
                val location = FCPoint(width - 25, 0)
                dropDownButton.location = location
                return dropDownButton
            } else if (clsid == "dropdownmenu") {
                val dropDownMenu = FCMenu()
                dropDownMenu.padding = FCPadding(1)
                dropDownMenu.setPopup(true)
                val size = FCSize(200, 200)
                dropDownMenu.size = size
                return dropDownMenu
            }
        }
        if (parent as? FCSpin != null) {
            if (clsid == "downbutton") {
                val downButton = FCButton()
                downButton.setDisplayOffset(false)
                downButton.text = "-"
                val size = FCSize(16, 16)
                downButton.size = size
                return downButton
            } else if (clsid == "upbutton") {
                val upButton = FCButton()
                upButton.setDisplayOffset(false)
                upButton.text = "+"
                val size = FCSize(16, 16)
                upButton.size = size
                return upButton
            }
        }
        if (parent as? FCDiv != null) {
            if (clsid == "hscrollbar") {
                val hScrollBar = FCHScrollBar()
                hScrollBar.isVisible = false
                val size = FCSize(4, 4)
                hScrollBar.size = size
                return hScrollBar
            } else if (clsid == "vscrollbar") {
                val vScrollBar = FCVScrollBar()
                vScrollBar.isVisible = false
                val size = FCSize(4, 4)
                vScrollBar.size = size
                return vScrollBar
            }
        }
        if (parent as? FCGrid != null) {
            if (clsid == "edittextbox") {
                return FCTextBox()
            }
        }
        return FCView()
    }

    /*
     * 查找预处理视图
     * view 视图
     */
    fun findPreviewsControl(control: FCView): FCView? {
        return if (control.allowPreviewsEvent()) {
            control
        } else {
            val parent = control.parent
            parent?.let { findPreviewsControl(it) }
        }
    }

    /*
     * 获取客户端的大小
     */
    val clientSize: FCSize
        get() {
            var size = FCSize()
            if (m_view != null) {
                size = FCSize(m_view!!.width, m_view!!.height)
            }
            return size
        }

    /*
     * 获取触摸位置
     */
    override fun getTouchPoint(): FCPoint {
        val mp = m_mousePoint.clone()
        if (m_native!!.allowScaleSize()) {
            val clientSize = clientSize
            if (clientSize.cx > 0 && clientSize.cy > 0) {
                val scaleSize = m_native!!.scaleSize
                mp.x = mp.x * scaleSize.cx / clientSize.cx
                mp.y = mp.y * scaleSize.cy / clientSize.cy
            }
        }
        return mp
    }

    /*
     * 获取裁剪区域
     * lpDestRect 裁剪区域
     * lpSrc1Rect 区域1
     * lpSrc2Rect 区域2
     */
    override fun getIntersectRect(
        lpDestRect: RefObject<FCRect>,
        lpSrc1Rect: RefObject<FCRect>,
        lpSrc2Rect: RefObject<FCRect>
    ): Int {
        lpDestRect.argvalue.left =
            Math.max(lpSrc1Rect.argvalue.left, lpSrc2Rect.argvalue.left)
        lpDestRect.argvalue.right =
            Math.min(lpSrc1Rect.argvalue.right, lpSrc2Rect.argvalue.right)
        lpDestRect.argvalue.top =
            Math.max(lpSrc1Rect.argvalue.top, lpSrc2Rect.argvalue.top)
        lpDestRect.argvalue.bottom =
            Math.min(lpSrc1Rect.argvalue.bottom, lpSrc2Rect.argvalue.bottom)
        return if (lpDestRect.argvalue.right > lpDestRect.argvalue.left && lpDestRect.argvalue.bottom > lpDestRect.argvalue.top) {
            1
        } else {
            lpDestRect.argvalue.left = 0
            lpDestRect.argvalue.right = 0
            lpDestRect.argvalue.top = 0
            lpDestRect.argvalue.bottom = 0
            0
        }
    }

    /*
     * 获取缩放比例
     */
    val scaleRate: Double
        get() = if (m_view != null) {
            val wm = m_view!!.context
                .getSystemService(Context.WINDOW_SERVICE) as WindowManager
            val outMetrics = DisplayMetrics()
            wm.defaultDisplay.getMetrics(outMetrics)
            val width = outMetrics.widthPixels
            val height = outMetrics.heightPixels
            Math.min(width, height).toDouble() / 430
        } else {
            1.0
        }

    /*
     * 转换触摸信息
     */
    fun getTouches(event: MotionEvent, touchInfo: FCTouchInfo): Int {
        val pointerCount = event.pointerCount
        for (i in 0 until pointerCount) {
            val mp = FCPoint(
                event.getX(i),
                event.getY(i)
            )
            if (m_native!!.allowScaleSize()) {
                val clientSize = clientSize
                if (clientSize.cx > 0 && clientSize.cy > 0) {
                    val scaleSize = m_native!!.scaleSize
                    mp.x = mp.x * scaleSize.cx / clientSize.cx
                    mp.y = mp.y * scaleSize.cy / clientSize.cy
                }
            }
            if (i == 0) {
                touchInfo.m_firstPoint = mp
                touchInfo.m_firstTouch = true
            } else if (i == 1) {
                touchInfo.m_secondPoint = mp
                touchInfo.m_secondTouch = true
            }
        }
        //ouchInfo.m_clicks = event.getPointerCount();
        return 1
    }

    /*
     * 获取大小
     */
    override fun getSize(): FCSize {
        return if (m_native!!.allowScaleSize()) {
            m_native!!.scaleSize
        } else {
            clientSize
        }
    }

    /*
     * 获取合并区域
     * lpDestRect 裁剪区域
     * lpSrc1Rect 区域1
     * lpSrc2Rect 区域2
     */
    override fun getUnionRect(
        lpDestRect: RefObject<FCRect>,
        lpSrc1Rect: RefObject<FCRect>,
        lpSrc2Rect: RefObject<FCRect>
    ): Int {
        return 0
    }

    /*
     * 秒表方法
     * lpParam 参数
     */
    fun invokeThread(lpParam: Any?): Int {
        if (lpParam is AndroidHost) {
            val androidHost = lpParam
            m_threadState = 1
            while (m_threadState == 1) {
                onTimer()
                try {
                    Thread.sleep(10)
                } catch (e: Exception) {
                    e.printStackTrace()
                }
            }
            m_threadState = 3
        }
        return 0
    }

    /*
     * 特殊键是否按下
     * key 按键
     */
    override fun isKeyPress(ch: Char): Boolean {
        return false
    }

    /*
     * 局部绘图
     * rect 区域
     */
    override fun invalidate(rect: FCRect) {
        if (m_allowPartialPaint) {
            val displaySize = m_native!!.size
            m_clipBounds.add(
                Rect(
                    if (rect.left >= 0) rect.left else 0,
                    if (rect.top >= 0) rect.top else 0,
                    if (rect.right <= displaySize.cx) rect.right else displaySize.cx,
                    if (rect.bottom <= displaySize.cy) rect.bottom else displaySize.cy
                )
            )
            m_view!!.postInvalidate()
        } else {
            invalidate()
        }
    }

    /*
     * 全部绘图
     */
    override fun invalidate() {
        m_clipBounds.clear()
        m_clipBounds.add(Rect(0, 0, m_native!!.size.cx, m_native!!.size.cy))
        m_view!!.invalidate()
    }

    /*
     * 跨线程调用
     * view 视图
     * args 参数
     */
    override fun invoke(control: FCView, args: Any) {
        synchronized(this) {
            m_handler!!.post { control!!.onInvoke(args) }
        }
    }

    /*
     * 重绘方法
     * g 绘图对象
     */
    fun onPaint(canvas: Canvas?) {
        try {
            if (canvas == null) {
                return
            }
            val width = canvas.width
            val height = canvas.height
            val displaySize = m_native!!.size
            val clipBoundsSize = m_clipBounds.size
            var clipRect = FCRect()
            if (clipBoundsSize > 0) {
                for (i in 0 until clipBoundsSize) {
                    val clipBounds = m_clipBounds[i]
                    if (i == 0) {
                        clipRect = FCRect(
                            clipBounds.left,
                            clipBounds.top,
                            clipBounds.right,
                            clipBounds.bottom
                        )
                    } else {
                        if (clipRect.left > clipBounds.left) {
                            clipRect.left = clipBounds.left
                        }
                        if (clipRect.right < clipBounds.right) {
                            clipRect.right = clipBounds.right
                        }
                        if (clipRect.top > clipBounds.top) {
                            clipRect.top = clipBounds.top
                        }
                        if (clipRect.bottom < clipBounds.bottom) {
                            clipRect.bottom = clipBounds.bottom
                        }
                    }
                }
            } else {
                clipRect = FCRect(0, 0, displaySize.cx, displaySize.cy)
            }
            m_clipBounds.clear()
            var scaleFactorX = 1.0
            var scaleFactorY = 1.0
            val clientSize = clientSize
            if (m_native!!.allowScaleSize()) {
                if (clientSize.cx > 0 && clientSize.cy > 0) {
                    val scaleSize = m_native!!.scaleSize
                    scaleFactorX = clientSize.cx.toDouble() / scaleSize.cx
                    scaleFactorY = clientSize.cy.toDouble() / scaleSize.cy
                }
            }
            val paint = m_native!!.paint
            val wRect = FCRect(0, 0, clientSize.cx, clientSize.cy)
            paint.setScaleFactor(scaleFactorX, scaleFactorY)
            (paint as? AndroidPaint)!!.setCanvas(canvas)
            paint.beginPaint(
                0,
                wRect,
                FCRect(clipRect.left, clipRect.top, clipRect.right, clipRect.bottom)
            )
            m_native!!.onPaint(clipRect)
            paint.endPaint()
        } catch (ex: Exception) {
            var a = 0;
            var b = 0;
        }
        //this.invalidate();
    }

    /*
     * 秒表方法
     */
    fun onTimer() {
        if (isViewVisible) {
            synchronized(m_timers) {
                try {
                    for (timer in m_timers.values) {
                        if (timer!!.m_tick % timer.m_interval == 0) {
                            m_runningTimerIDs.add(timer.m_timerID)
                        }
                        timer.m_tick++
                    }
                } catch (ex: Exception) {
                }
            }
            if (m_runningTimerIDs.size > 0) {
                m_handler!!.post {
                    synchronized(m_timers) {
                        try {
                            val runningTimerIDsSize = m_runningTimerIDs.size
                            for (i in 0 until runningTimerIDsSize) {
                                m_native!!.onTimer(m_runningTimerIDs[i])
                            }
                            m_runningTimerIDs.clear()
                        } catch (ex: Exception) {
                        }
                    }
                }
            }
        }
    }

    /*
     * 粘贴数据
     */
    override fun paste(): String {
        if (m_clipboard == null) {
            m_clipboard = m_view!!.context
                .getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
        }
        val clipData = m_clipboard!!.primaryClip
        if (clipData != null && clipData.itemCount > 0) {
            val text = clipData.getItemAt(0).text
            return text.toString()
        }
        return ""
    }

    /*
     * 运行线程
     */
    override fun run() {
        invokeThread(this)
    }

    /*
     * 设置第二个点
     * mp 坐标
     */
    fun setTouchPoint(mp: FCPoint) {
        m_mousePoint = mp.clone()
    }

    /*
     * 显示提示框
     * var1 字符串
     * var2 坐标
     */
    override fun showToolTip(var1: String, var2: FCPoint) {}
    override fun startTimer(timerID: Int, interval: Int) {
        var interval = interval
        interval = interval / 10
        if (interval < 1) {
            interval = 1
        }
        synchronized(m_timers) {
            if (m_timers.containsKey(timerID)) {
                val timer = m_timers[timerID]
                timer!!.m_interval = interval
                timer.m_tick = 0
            } else { /*
                 * 启动秒表
                 * timerID 秒表ID
                 * interval 间隔
                 */
                val timer = AndroidTimer()
                timer.m_interval = interval
                timer.m_timerID = timerID
                m_timers.put(timerID, timer)
            }
        }
    }

    /*
     * 结束秒表
     * timerID 秒表ID
     */
    override fun stopTimer(timerID: Int) {
        synchronized(m_timers) {
            if (m_timers.containsKey(timerID)) {
                m_timers.remove(timerID)
            }
        }
    }

    /*
     * 删除资源
     */
    override fun delete() {}

    /*
     * 获取光标
     */
    override fun getCursor(): FCCursors {
        return FCCursors.Arrow
    }

    /*
     * 设置光标
     */
    override fun setCursor(var1: FCCursors) {}

    companion object {
        fun dp2px(context: Context, dpValue: Float): Int {
            val scale = context.resources.displayMetrics.density
            return (dpValue * scale + 0.5f).toInt()
        }
    }
}